package com.tsk.example.api.controller;

import com.tsk.example.api.model.DemoParamsVO;
import com.tsk.example.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.util.HashMap;
import java.util.Map;

/** 示例控制器DemoController
 * @author: 黄嘉振
 * @create: 2023/3/7 15:25
 * @description: POST请求，使用requestBody传递参数；
 *               GET请求，使用requestParam/PathVariable传递参数
 *               建议一个方法中仅使用一种方式进行参数传递，避免人为引入复杂度
 **/
@Slf4j
@RestController
@Validated
@RequestMapping("/demo")
public class DemoController {

    /**
     * 测试方法，模拟返回字符串结果
     * 返回字符串时，需要说明json application/json;charset=UTF-8
     * @return  结果
     */
    @GetMapping(value = "testString", produces = "application/json;charset=UTF-8")
    public String testString() {
        return "test";
    }

    /**
     * 模拟异常，统一封装异常信息
     * @return  异常字符串
     */
    @GetMapping(value = "mockException")
    public String mockException() {
        throw new BusinessException("模拟异常场景");
    }

    /**
     * 校验数值在[1,10]范围内
     * 适用于从路径上获取变量的场景
     * 获取的是url路径上某个变量的值，如 localhost:port/demo/1、localhost:port/demo/2等
     * @param num   数值
     * @return  结果
     */
    @GetMapping("/{num}")
    public Integer validPathParams(@PathVariable("num") @Min(1) @Max(10) Integer num) {
        log.info("获取的数值：" + num);
        return num;
    }

    /**
     * 校验请求参数
     * 仅适用于参数较少的情况，参数较多时建议使用实体接收
     * 获取的是url?后的参数，如localhost:port/demo/validRequestParams?name=xxx&age=xxx
     * @param name  姓名
     * @param age   年龄
     * @return  结果
     */
    @GetMapping("/validRequestParams")
    public Map validRequestParams(@RequestParam(value = "name") @NotNull String name,
                                  @RequestParam(value = "age") @Min(value = 0, message = "年龄不能小于0") @Max(value = 150, message = "年龄最大150") Integer age) {
        Map<String, Object> map = new HashMap(8);
        map.put(name, age);
        log.info("map: " +map);
        return map;
    }

    /**
     * 校验请求体参数
     * 适用于参数较多的场景
     * 获取的是请求体中的参数，由于是实体接收，所以请求body里需要添加{}
     * @param vo    实体
     * @return  结果
     */
    @PostMapping("/validRequestBody")
    public Map validRequestBody(@RequestBody @Validated DemoParamsVO vo) {
        log.info("get params: " + vo);
        Map<Object, Object> result = new HashMap<>(8);
        result.put("name", vo.getName());
        result.put("age", vo.getAge());
        result.put("addr", vo.getAddr());
        return result;
    }
}
